package logger

import (
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"io"
	"os"
	"time"
)

var PanicLogger *zap.Logger
var InfoLogger *zap.Logger
var ErrorLogger *zap.Logger

func CreateLog(path string) error {
	_, err := os.Stat(path + "/logs")
	if os.IsNotExist(err) {
		err := os.Mkdir(path+"/logs", os.ModePerm)
		if err != nil {
			return err
		}
	}
	err = os.Chmod(path+"/logs", os.ModePerm)
	if err != nil {
		return err
	}

	_, err = os.Stat(path + "/logs/panic")
	if os.IsNotExist(err) {
		err = os.Mkdir(path+"/logs/panic", os.ModePerm)
		if err != nil {
			return err
		}
	}
	err = os.Chmod(path+"/logs/panic", os.ModePerm)
	if err != nil {
		return err
	}

	_, err = os.Stat(path + "/logs/info")
	if os.IsNotExist(err) {
		err = os.Mkdir(path+"/logs/info", os.ModePerm)
		if err != nil {
			return err
		}
	}
	err = os.Chmod(path+"/logs/info", os.ModePerm)
	if err != nil {
		return err
	}

	_, err = os.Stat(path + "/logs/error")
	if os.IsNotExist(err) {
		err = os.Mkdir(path+"/logs/error", os.ModePerm)
		if err != nil {
			return err
		}
	}
	err = os.Chmod(path+"/logs/error", os.ModePerm)
	if err != nil {
		return err
	}

	return nil
}

func InitLogger(level string) {
	encoder := zapcore.NewJSONEncoder(zapcore.EncoderConfig{
		MessageKey:    "msg",
		LevelKey:      "level",
		TimeKey:       "ts",
		CallerKey:     "path",
		StacktraceKey: "stack",
		EncodeLevel:   zapcore.CapitalLevelEncoder,
		EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
			encoder.AppendString(t.Format("2006-01-02 15:04:05"))
		},
		EncodeCaller: zapcore.ShortCallerEncoder,
	})

	// 级别 debug->info->warn->error
	// highLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
	// 	return lvl >= zapcore.DebugLevel
	// })

	// lowLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
	// 	return lvl < zapcore.DebugLevel
	// })

	if level == "panic" {
		hook1 := getWriter("logs/panic/panic")
		core := zapcore.NewTee(
			zapcore.NewCore(encoder, zapcore.AddSync(hook1), zapcore.DebugLevel),
			zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
		)
		logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2))
		PanicLogger = logger
	}
	if level == "error" {
		hook1 := getWriter("logs/error/error")
		core := zapcore.NewTee(
			zapcore.NewCore(encoder, zapcore.AddSync(hook1), zapcore.DebugLevel),
			zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
		)
		logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2))
		ErrorLogger = logger
	}
	if level == "info" {
		hook1 := getWriter("logs/info/info")
		core := zapcore.NewTee(
			zapcore.NewCore(encoder, zapcore.AddSync(hook1), zapcore.DebugLevel),
			zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
		)
		logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2))
		InfoLogger = logger
	}
}

func getWriter(filename string) io.Writer {
	hook, err := rotatelogs.New(
		filename+".%Y%m%d",
		rotatelogs.WithLinkName(filename),
		rotatelogs.WithMaxAge(time.Hour*24*14),
		rotatelogs.WithRotationTime(time.Hour*24),
	)

	if err != nil {
		panic(err)
	}
	return hook
}
